/*
 * Copyright (c) 2013-2015 Charkey. All rights reserved.
 *
 * This software is the confidential and proprietary information of Charkey.
 * You shall not disclose such Confidential Information and shall use it only
 * in accordance with the terms of the agreements you entered into with Charkey.
 *
 * Charkey MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE SOFTWARE,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
 *
 * Charkey SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING,
 * MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
 */

package cn.simastudio.talos.inter.service.inst.impl;

import cn.simastudio.talos.common.utils.RandomDigitsGenerator;
import cn.simastudio.talos.core.exception.biz.DataUpdateException;
import cn.simastudio.talos.core.exception.system.ComponentMissingException;
import cn.simastudio.talos.core.service.base.impl.PasswordService;
import cn.simastudio.talos.inter.enums.SMSTemplate;
import cn.simastudio.talos.inter.mapper.inst.MemberMapper;
import cn.simastudio.talos.inter.model.inst.Member;
import cn.simastudio.talos.inter.service.inst.MemberService;
import cn.simastudio.talos.ucpaas.client.UCPaaSClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.List;

@Service
public class MemberServiceImpl implements MemberService {

    private static final int DEFAULT_UPDATE_COUNT = 1;

    private static final int DEFAULT_DELETE_COUNT = 1;

    @Autowired(required = false)
    private UCPaaSClient ucPaaSClient;

    /**
     * 密码服务类：提供密码加密、校验匹配
     */
    @Autowired
    private PasswordService passwordService;

    @Autowired
    private MemberMapper memberMapper;

    @Autowired
    private CacheManager cacheManager;

    private Cache configurationCache;

    @PostConstruct
    public void afterPropertiesSet() {
        configurationCache = cacheManager.getCache("configurationCache");
    }

    /**
     * @param member member
     * @return member
     */
    public Member createMember(Member member) {
        //进行密码加密
        String salt = passwordService.getRandomSalt();
        // Sima: 注意这边生成密码加密的方式需要和Realm中CredentialsSalt的取得相对应，即密码如果是用户名和密码和加密盐去hash的，CredentialsSalt就要取用户名和加密盐来hash
        String encryptPassword = passwordService.encryptPassword(member.getPassword(), salt);
        //设置加密的密码
        member.setPassword(encryptPassword);
        //设置加密用的加密盐
        member.setSalt(salt);
        //设置UUID
        //member.setUuid(String.valueOf(UUID.randomUUID()));
        //插入数据库
        int memberRes = memberMapper.insertSelective(member);
        // 没必要返回这两个字段信息
        member.setPassword(null);
        member.setSalt(null);
        return memberRes == DEFAULT_UPDATE_COUNT ? member : null;
    }

    @Override
    public Member updateMember(Member member) {
        return null;
    }

    @Override
    public void deleteMember(Long memberId) {
    }

    public void changePassword(Long memberId, String newPassword) {

    }

    @Override
    public Member findOne(Long memberId) {
        return null;
    }

    @Override
    public Member getMemberByName(String name) {
        Member member = memberMapper.getMemberByUsername(name);
        if (member == null) {
            return null;
        }
        // 没必要返回这两个字段信息
        member.setPassword(null);
        member.setSalt(null);
        return member;
    }

    @Override
    public Member login(String username, String password) {
        //根据会员注册手机号查找会员信息
        Member member = getMemberByName(username);
        //校验密码
        passwordService.validate(member.getUsername(), member.getSalt(), member.getPassword(), password);
        //登录成功
        // 没必要返回这两个字段信息
        member.setPassword(null);
        member.setSalt(null);
        return member;
    }


    @Override
    public List<Member> findAll() {
        return null;
    }

    /**
     * 根据会员名查找信息
     *
     * @param memberName 会员名
     * @return 会员信息Member对象
     */
    public Member findByMemberNameForAuth(String memberName) {
        return memberMapper.getMemberByUsername(memberName);
    }

    @Override
    public List<Member> getMemberList(Member member) {
        return memberMapper.getMemberListLikeUsername(member);
    }

    @Override
    public Member resetPassword(String username) {
        Member member = getMemberByName(username);
        if (member == null) {
            return null;
        }
        //进行密码加密
        String salt = passwordService.getRandomSalt();

        String UCPaaSDefaultPasswordLength = configurationCache.get("UCPaaSDefaultPasswordLength").get() + "";
        // 生成纯数字验证码，具体多少位配置在数据库中，key为UCPaaSDefaultPasswordLength
        RandomDigitsGenerator randomDigitsGenerator = new RandomDigitsGenerator(Integer.parseInt(UCPaaSDefaultPasswordLength));
        String password = randomDigitsGenerator.random();

        String encryptPassword = passwordService.encryptPassword(password, salt);
        //设置加密的密码
        member.setPassword(encryptPassword);
        //设置加密用的加密盐
        member.setSalt(salt);
        updateMember(member);
        // Sima: member need more details, such as tel.
        String tel = "18259055729";
        try {
            if (ucPaaSClient == null) {
                throw new ComponentMissingException();
            }
            ucPaaSClient.sendSMS(password, tel, SMSTemplate.NoticePassword.getInfo());
        } catch (IOException e) {
            throw new DataUpdateException();
        }
        // Sima: 这边将新密码（明文）明文设置给Member对象，方便控制器返回密码给客户端
        member.setPassword(password);
        return member;
    }

    @Override
    public Member changePassword(String username, String oldPassword, String newPassword) {
        Member member = login(username, oldPassword);
        if (member != null) {
            //进行密码加密
            String salt = passwordService.getRandomSalt();
            String tel = "18259055729";
            String encryptPassword = passwordService.encryptPassword(newPassword, salt);
            //设置加密的密码
            member.setPassword(encryptPassword);
            //设置加密用的加密盐
            member.setSalt(salt);
            updateMember(member);
            return member;
        }
        return null;
    }

}
